#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<stdlib.h>
#include<time.h>
#include<pwd.h>
#include<grp.h>
#include<string.h>
#include <dirent.h>
#include <unistd.h>

int process_ls(const char *arg)
{
// printf("argv=%s\n",arg);
    // printf("process_ls\n");
    struct dirent *dt;
    DIR *dirp = opendir(arg);
    if (dirp == NULL)
    {
        perror("opendir");
        exit(-1);
    }
    while ((dt = readdir(dirp)) != NULL)
    {
        if (strncmp(dt->d_name, ".", 1) == 0)
            continue;
        printf("%s  ", dt->d_name);
    }
    printf("\n");
    closedir(dirp);
    return 0;
}

int process_ls_l(const char *arg)
{
struct dirent *dt;
    struct stat st;
    char filename[300] = {0};
    struct tm *tmp;
    DIR *dirp = opendir(arg);
    if (dirp == NULL)
    {
        perror("opendir");
        exit(-1);
    }
    while ((dt = readdir(dirp)) != NULL)
    {
        if (strncmp(dt->d_name, ".", 1) == 0)
            continue;

        if (arg[strlen(arg) - 1] == '/')
        {
            sprintf(filename, "%s%s", arg, dt->d_name);
        }
        else
        {
            sprintf(filename, "%s/%s", arg, dt->d_name);
        }

        //printf("%s\n", filename);

        int ret = stat(filename, &st);
        if (ret < 0)
        {
            perror("stat");
            exit(-1);
        }
        switch (st.st_mode & S_IFMT)
        {
        case S_IFBLK:
            printf("b");
            break;
        case S_IFCHR:
            printf("c");
            break;
        case S_IFDIR:
            printf("d");
            break;
        case S_IFIFO:
            printf("p");
            break;
        case S_IFLNK:
            printf("l");
            break;
        case S_IFREG:
            printf("-");
            break;
        case S_IFSOCK:
            printf("s");
            break;
        default:
            printf("unknown?");
            break;
        }
        /********用户*********/
        //获取用户的可读权限
        if (st.st_mode & S_IRUSR)
            printf("r");
        else
            printf("-");
        //获取用户的可写权限
        if (st.st_mode & S_IWUSR)
            printf("w");
        else
            printf("-");
        //获取用户的可执行权限
        if (st.st_mode & S_IXUSR)
            printf("x");
        else
            printf("-");

        /**************组*******************************/
        if (st.st_mode & S_IRGRP)
            printf("r");
        else
            printf("-");
        if (st.st_mode & S_IWGRP)
            printf("w");
        else
            printf("-");
        if (st.st_mode & S_IXGRP)
            printf("x");
        else
            printf("-");

        /**************其他用户的权限****************************/
        if (st.st_mode & S_IROTH)
            printf("r");
        else
            printf("-");
        if (st.st_mode & S_IWOTH)
            printf("w");
        else
            printf("-");
        if (st.st_mode & S_IXOTH)
            printf("x");
        else
            printf("-");

        /**************文件硬链接********************/
        printf(" %ld ", st.st_nlink); //输出文件硬链接

        /**************文件所有者，所属组********************/
        struct passwd *pw = getpwuid(st.st_uid);
        printf(" %s ", pw->pw_name);
        struct group *grp = getgrgid(st.st_gid);
        printf(" %s  ", grp->gr_name);

        /**************文件大小********************/
        printf("%5ld ", st.st_size); //输出文件大小（\t 加上一个tab按键，等于4个空格

        /**************文件时间********************/
        struct tm *tmp = localtime(&st.st_mtime); // st_atime 就是秒数
        // struct tm *tmp = localtime(&st.st_atime); // st_atime 就是秒数
        printf("%02d月  %02d %02d:%02d ", tmp->tm_mon + 1, tmp->tm_mday,
               tmp->tm_hour, tmp->tm_min);

        /**************文件名********************/
        printf(" %s \n", dt->d_name); //输出文件名 
    }
    return 0;
}
int main(int argc, char const *argv[])
{
    if (argc == 2)
    {
        process_ls(argv[1]);
    }
    else if(argc == 3)
    {
        process_ls_l(argv[2]);
    }
    else
    {
        fprintf(stderr, "程序错误：运行程序时请带入参数./30myls \n");
        exit(-1);
    }

#if 0
    struct dirent *dt;
    struct stat st;

    if (argc == 3)
    {
        chdir(argv[2]);

        DIR *dirp = opendir(argv[2]);
        if (dirp == NULL)
        {
            perror("opendir");
            exit(-1);
        }
        while ((dt = readdir(dirp)) != NULL)
        {
            if (strncmp(dt->d_name, ".", 1) == 0)
                continue;
            int ret = stat(dt->d_name, &st);
            if (ret < 0)
            {
                perror("stat");
                exit(-1);
            }
            switch (st.st_mode & S_IFMT)
            {
            case S_IFBLK:
                printf("b");
                break;
            case S_IFCHR:
                printf("c");
                break;
            case S_IFDIR:
                printf("d");
                break;
            case S_IFIFO:
                printf("p");
                break;
            case S_IFLNK:
                printf("l");
                break;
            case S_IFREG:
                printf("-");
                break;
            case S_IFSOCK:
                printf("s");
                break;
            default:
                printf("unknown?");
                break;
            }
            /********用户*********/
            //获取用户的可读权限
            if (st.st_mode & S_IRUSR)
                printf("r");
            else
                printf("-");
            //获取用户的可写权限
            if (st.st_mode & S_IWUSR)
                printf("w");
            else
                printf("-");
            //获取用户的可执行权限
            if (st.st_mode & S_IXUSR)
                printf("x");
            else
                printf("-");

            /**************组*******************************/
            if (st.st_mode & S_IRGRP)
                printf("r");
            else
                printf("-");
            if (st.st_mode & S_IWGRP)
                printf("w");
            else
                printf("-");
            if (st.st_mode & S_IXGRP)
                printf("x");
            else
                printf("-");

            /**************其他用户的权限****************************/
            if (st.st_mode & S_IROTH)
                printf("r");
            else
                printf("-");
            if (st.st_mode & S_IWOTH)
                printf("w");
            else
                printf("-");
            if (st.st_mode & S_IXOTH)
                printf("x");
            else
                printf("-");

            /**************文件硬链接********************/
            printf(" %ld ", st.st_nlink); //输出文件硬链接

            /**************文件所有者，所属组********************/
            struct passwd *pw = getpwuid(st.st_uid);
            printf(" %s ", pw->pw_name);      
            struct group *grp = getgrgid(st.st_gid);
            printf(" %s ", grp->gr_name);

            /**************文件大小********************/
            printf(" %ld ", st.st_size);   //输出文件大小（\t 加上一个tab按键，等于4个空格

            /**************文件时间********************/
            struct tm *tmp = localtime(&st.st_mtime); // st_atime 就是秒数
            //struct tm *tmp = localtime(&st.st_atime); // st_atime 就是秒数
            printf("%02d月  %02d %02d:%02d ", tmp->tm_mon + 1, tmp->tm_mday,
                   tmp->tm_hour, tmp->tm_min);

            /**************文件名********************/
            printf(" %s \n", dt->d_name); //输出文件名
        }
    }
    else if (argc == 2)
    {
        chdir(argv[1]);
        DIR *dirp = opendir(argv[1]);
        if (dirp == NULL)
        {
            perror("opendir");
            exit(-1);
        }
        while ((dt = readdir(dirp)) != NULL)
        {
            if (strncmp(dt->d_name, ".", 1) == 0)
            {
                continue;
            }

            printf("%s  ", dt->d_name);
        }
        printf("\n");
        closedir(dirp);
    }
    else
    {
        fprintf(stderr, "程序错误：运行程序时请带入参数./30myls \n");
        exit(-1);
    }
#endif   

    return 0;
}